#ifndef ACPI_H_
#define ACPI_H_

#include <types.h>

#define RSDP_SIGNATURE "RSD PTR "
#define RSDP_START 0x000E0000
#define RSDP_END 0x000FFFFF

#define ERR_ACPI_NOTFOUND 1
#define ERR_ACPI_RSDT_NOTFOUND 2

typedef struct acpi_rsdp_descriptor
{
	char signature[8];
 	byte checksum;
 	byte oem_id[6];
 	byte revision;
 	dword rsdt_addr;
} __attribute__((packed)) acpi_rsdp_descriptor_t;

/* don't care to implement v2+
typedef struct acpi_rsdp2_descriptor
{
	acpi_rsdp_descriptor_t rsdp1_descriptor;
	
 	dword length;
 	dword xsdt_address[2];
 	byte ext_checksum;
 	byte reserved[3];
} __attribute__((packed)) acpi_rsdp2_descriptor_t;
*/

typedef struct acpi_system_descriptor
{
	char signature[4];
	dword length;
	byte revision;
	byte checksum;
	byte oem_id[6];
	byte oem_table_id[8];
	dword oem_revision;
	byte creator_id[4];
	dword creator_revision;
} __attribute__((packed)) acpi_system_descriptor_t;

typedef struct acpi_rsdt_descriptor
{
	acpi_system_descriptor_t header;
	acpi_system_descriptor_t *descriptor_ptrs[];
} __attribute__((packed)) acpi_rsdt_descriptor_t;

typedef struct acpi_xsdt_descriptor
{
	acpi_system_descriptor_t header;
	dword *descriptor_ptrs;  // todo: should be 64-bit ptrs
} __attribute__((packed)) acpi_xsdt_descriptor_t;

typedef struct acpi_fadt_descriptor
{
	acpi_system_descriptor_t header;
	dword facs;
	dword dsdt;
	byte resv; // int_model
	byte pref_pm;
	word sci_int;
	dword smi_cmd;
	byte acpi_enable;
	byte acpi_disable;
	byte s4bios_req;
	// todo: finish this or find an impl online
} __attribute__((packed)) acpi_fadt_descriptor_t;

acpi_rsdp_descriptor_t * find_rsdp(void *start, void *end);
int acpi_parse_rsdp(acpi_rsdp_descriptor_t *rsdp);
int init_acpi(void);

#endif /*ACPI_H_*/
